xpk.dhtmlPanels = {};

xpk.dhtmlPanel = function(element, options){
	var $this;
	var _this = new xpk.Class({
		options: {
			duration: 300,
			toggle: true,
			itemSelector: '.item'
		},
		isSwap: false,
		init: function(options){
			$this = $(this);			
			this.wrapper = $(element).hide();			
			this.setOptions(options);

			this.panels = this.options.itemSelector ? this.wrapper.find(this.options.itemSelector) : this.wrapper.children();
			this.panels.hide().data('slider', this);

			this.offset = {
				top: this.wrapper.css('marginTop'),
				bottom: this.wrapper.css('marginBottom')
			};
			
			if(this.options.onshow) {
				$this.bind('onshow', this.options.onshow)
			};
			if(this.options.onhide) {
				$this.bind('onhide', this.options.onhide)
			};			
			
			$this.bind('onshow', function(){
				$.fx.off = false;
			});
			
			this.opened = false;
			this.activeElement = null;
			this.pendingElement = null;
			return this;
		},
		hide: function(_set){
			$.fx.off = _set;
			return this.slide('up');
		},
		show: function(_panel, _set){
			$.fx.off = _set;			
			var swap = this.opened && this.activeElement ? this.activeElement : false; // swap == true indicates that we have a panel opened
			this.pendingElement = $(_panel);
			try{
				if(this.activeElement[0] == this.pendingElement[0]) {
					if(!this.options.toggle) $.fx.off = false;
					return this.options.toggle ? this.hide() : this;
				};
			} catch(e){};
			this.activeElement = this.opened ? this.activeElement : this.pendingElement;
			return this.slide(this.opened ? 'swap' : 'down');
		},
		toggle: function(_panel){
			if(this.opened){
				return this.opened ? this.hide() : this.show(_panel);
			};
		},
		slide: function(direction, quick){
			
			var slideCallback;
			var _wrapCss = {};
			
			var duration = this.options.duration;
			this.wrapper.css('overflow', 'hidden');
			
			switch(direction){
				case 'swap': 
					var _elementHeight = this.activeElement.outerHeight(true);
					this.wrapper.css('height', _elementHeight);
					_wrapCss = {};
					_marginTop =  -1 * _elementHeight;
					duration = duration / 2;
					
					slideCallback = function(){
						this.activeElement.hide();
						$this.trigger('onhide', this);
						
						this.activeElement = this.pendingElement;
						this.slide('down', true);
					};					

					break;
				case 'down':

					_wrapCss = quick ? {} : {
						display: 'block', height: 0
					};
					
					this.wrapper.css(_wrapCss);
					this.activeElement.show();

					var _elementHeight = this.activeElement.outerHeight();
					var _marginTop = 0;
					
					_wrapCss = {
						height: _elementHeight, marginTop: this.offset.top, marginBottom: this.offset.bottom
					};
					
					this.activeElement.css('marginTop', -1 * _elementHeight);
					
					slideCallback = function(){
						this.wrapper.css({height: '', overflow: ''});
						this.opened = true;
						$this.trigger('onshow', this);
					};
					
					break;
				case 'up':
				
					duration = duration / 2;
					var _elementHeight = this.activeElement.outerHeight();
					var _marginTop = -1 * _elementHeight;

					_wrapCss = {
						height: 0, marginTop: 0, marginBottom: 0
					};
					slideCallback = function(){
						this.activeElement.hide();
						this.wrapper.css({display: 'none', 'overflow': ''});

						$this.trigger('onhide', this);
						
						this.opened = false;
						this.activeElement = null;
						this.pendingElement = null;
						
					};

					break;
				default:
					return this;
			};
					
			this.wrapper.stop().animate(_wrapCss, {duration: duration});

			this.activeElement.stop().animate({marginTop: _marginTop}, {
				duration: duration,
				complete: function(){
					slideCallback.call(_this);
					
				}
			});
			
			if($.fx.off) slideCallback.call(_this);
			
			return this;
		}
		
	});
	return _this.init(options);
};

(function($){
		  
	$.fn.slider = function(_direction, options){
		return this.each(function(){
			var $element = $(this);
			var slider = $element.data('slider');
			if(!slider) {
				slider = new xpk.Slider($element, options);
				$element.data('slider', slider);
			};

			switch(_direction){
				case 'show':
					slider.show($element);
					break;
				case 'hide':
					slider.hide();
					break;
				default:
					slider.toggle($element);
					break;
			};
		});
	};
	
})(jQuery);